/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vn.org.hcmut.or.model;

import java.util.ArrayList;
import java.util.Hashtable;

/**
 *
 * @author HUNGUYEN
 */
public class SchedulingInfo {
    private int numOfJob;
    private int minsplit;
    private int numOfDuration;
    private ArrayList<AvailableWindow> aWindow;
    private ArrayList<AvailableJob> aJob;
    private int timeTotal;
    private Hashtable<Integer, ArrayList<AvailableWindow>> hashTableWindow;
    private Hashtable<Integer, ArrayList<AvailableJob>> hashTableJob;
    

    public Hashtable<Integer, ArrayList<AvailableWindow>> getHashTableWindow() {
		return hashTableWindow;
	}

	public void setHashTableWindow(
			Hashtable<Integer, ArrayList<AvailableWindow>> hashTableWindow) {
		this.hashTableWindow = hashTableWindow;
	}

	public Hashtable<Integer, ArrayList<AvailableJob>> getHashTableJob() {
		return hashTableJob;
	}

	public void setHashTableJob(
			Hashtable<Integer, ArrayList<AvailableJob>> hashTableJob) {
		this.hashTableJob = hashTableJob;
	}

	public ArrayList<AvailableJob> getaJob() {
		return aJob;
	}

	public void setTimeTotal(int timeTotal) {
		this.timeTotal = timeTotal;
	}

	public void setaJob(ArrayList<AvailableJob> aJob) {
        this.aJob = aJob;
    }

    public ArrayList<AvailableWindow> getaWindow() {
        return aWindow;
    }

    public void setaWindow(ArrayList<AvailableWindow> aWindow) {
        this.aWindow = aWindow;
    }

    public int getMinsplit() {
        return minsplit;
    }

    public void setMinsplit(int minsplit) {
        this.minsplit = minsplit;
    }

    public int getNumOfDuration() {
        return numOfDuration;
    }

    public void setNumOfDuration(int numOfDuration) {
        this.numOfDuration = numOfDuration;
    }

    public int getNumOfJob() {
        return numOfJob;
    }

    public void setNumOfJob(int numOfJob) {
        this.numOfJob = numOfJob;
    }

    public int getTimeTotal() {
        int indexJob = findCurUpdateMax();
        timeTotal = aWindow.get(indexJob).getTimeStart();
        for (int index = 0; index<aJob.size();index++){
            timeTotal+=aJob.get(index).getDurationJobInWindow().get(indexJob);
        }
        return timeTotal;
    }
    
    public int findCurUpdateMax(){
        int value = aJob.get(0).getCurPosUpdate();
        
        for (int index = 1;index<aJob.size();index++){
            value = Math.max(value,aJob.get(index).getCurPosUpdate());
        }
        return value;
    }
    public int getSplitTotal(){
        int countTotal=0;
        for (int index = 0; index < aJob.size();index++){
            countTotal+=aJob.get(index).getNumFragInArangeWindow();
        }
        return countTotal;
    }
    public void buildAavaibleWindowHashTable()
    {
    	hashTableWindow = new Hashtable<Integer, ArrayList<AvailableWindow>>();
    	for(int i = 0;i<aWindow.size();i++)
    	{
    		AvailableWindow aw = aWindow.get(i);
    		if(aw.isProcess())
    			continue;
    		if(hashTableWindow.containsKey(aw.getT_duration()- aw.getDurationWinCurrent()))
    		{
    			ArrayList<AvailableWindow> law = hashTableWindow.get(aw.getT_duration() - aw.getDurationWinCurrent());
    			law.add(aw);
    			hashTableWindow.remove(aw.getT_duration());
    			hashTableWindow.put(aw.getT_duration(), law);
    		}
    		else
    		{
    			ArrayList<AvailableWindow> law = new ArrayList<AvailableWindow>();
    			law.add(aw);
    			hashTableWindow.put(aw.getT_duration()-aw.getDurationWinCurrent(), law);
    		} 		
    	}
    }
    
    public void buildAavaibleJobHashTable()
    {
    	hashTableJob = new Hashtable<Integer, ArrayList<AvailableJob>>();
    	for(int i = 0;i<aJob.size();i++)
    	{
    		AvailableJob aj = aJob.get(i);
    		if(hashTableJob.containsKey(aj.getProTimeJob()))
    		{
    			ArrayList<AvailableJob> laj = hashTableJob.get(aj.getProTimeJob());
    			laj.add(aj);
    			hashTableJob.remove(aj.getProTimeJob());
    			hashTableJob.put(aj.getProTimeJob(), laj);
    		}
    		else
    		{
    			ArrayList<AvailableJob> laj = new ArrayList<AvailableJob>();
    			laj.add(aj);
    			hashTableJob.put(aj.getProTimeJob(), laj);
    		} 		
    	}
    }
    
    public void buildSplitJobByHeuristic()
    {
    	//System.out.println("splitJobByHeuristic is running");
    	for(int i = 0;i<aJob.size();i++)
    	{
    		AvailableJob aj = aJob.get(i);
			ArrayList<FragmentJob> listFragmentJob = new ArrayList<FragmentJob>();
    		if(aj.getProTimeJob() > minsplit && aj.getProTimeJob() < 2*minsplit)
    		{
    			
    		}
    		else if(hashTableWindow.get(aj.getProTimeJob()) != null)
    		{
    	//		System.out.println("splitJobByHeuristic : Job "+aj.getId() +" fit with window");
    		}
    		else if(aj.getProTimeJob() > 2*minsplit)
    		{
    			int splitJob = aj.getProTimeJob()/minsplit;
    			int heuristicFragment = splitJob/2;
    			if(heuristicFragment == 1){
    				aJob.get(i).setListFragJob(listFragmentJob);  
    				aj.setFragment(false);
    				continue;
    			}
    			int sum = 0;
    			for(int j = 0;j<heuristicFragment;j++)
    			{
    				//create fragment job here
    				FragmentJob fj = new FragmentJob();
    				if(j==heuristicFragment-1)
    				{
    					int finalJobSplitTime = aj.getProTimeJob() - sum;
    					fj.setId(aj.getIdJob());
    					fj.setOrder(j);
    					fj.setProcessingTime(finalJobSplitTime);
    					fj.setStatus(false);
    					aj.setFragment(true);
    				}
    				else
    				{
    					int jobSplitTime = aj.getProTimeJob()/heuristicFragment;
    					sum += jobSplitTime;
    					fj.setId(aj.getIdJob());
    					fj.setOrder(j);
    					fj.setProcessingTime(jobSplitTime);
    					fj.setStatus(false);
    				}
    				listFragmentJob.add(fj);
    			}
    			
    		}
    		aJob.get(i).setListFragJob(listFragmentJob);   		
    	}
    }
}
